package rhc.common.util;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;


import org.codehaus.jackson.JsonParseException;
import org.codehaus.jackson.map.JsonMappingException;
import org.codehaus.jackson.map.ObjectMapper;
import org.codehaus.jackson.type.JavaType;
import org.springframework.data.mongodb.core.mapping.Field;
import org.springframework.util.StringUtils;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;

import rhc.common.entity.AbstractDocument;

public class NormalUtil {

	/**
	 * 构造接口返回数据
	 * 
	 * @return
	 */
	public static String buildJson(String status, String message, Object data) {
		String json = "";
		json = "{\"code\":" + status + ",\"message\":\"" + message + "\",\"data\":" + data + "}";
		return json;
	}

	/**
	 * 新版生成json方法
	 * 
	 * @param status
	 * @param message
	 * @param data
	 * @return
	 */
	public static String buildJsonNew(String status, String message, Object data) {

		Map<String, Object> result = new HashMap<String, Object>();
		result.put("code", status);
		result.put("message", message);
		result.put("data", data);

		ObjectMapper mapper = new ObjectMapper();

		try {
			if (data instanceof JSONObject || data instanceof JSONArray) {
				return "{\"code\":" + status + ",\"message\":\"" + message + "\",\"data\":" + data + "}";
			}
			return mapper.writeValueAsString(result);
		} catch (IOException e) {
			e.printStackTrace();
			return "{\"code\":" + status + ",\"message\":\"" + message + "\",\"data\":" + data + "}";
		}
	}

	/**
	 * json化data对象返回
	 * 
	 * @param data
	 * @return
	 */
	public static String buildJsonNew(Object data) {

		if (null == data) {
			return null;
		}

		ObjectMapper mapper = new ObjectMapper();
		try {
			return mapper.writeValueAsString(data);
		} catch (IOException e) {
			e.printStackTrace();
			return data.toString();
		}
	}

	/**
	 * 用以json bean化
	 */
	private final static ObjectMapper mapper = new ObjectMapper();

	/**
	 * 将json转换beanlist
	 * 
	 * @param jsonString
	 * @param beanClasses
	 * @return
	 * @throws IOException
	 * @throws JsonMappingException
	 * @throws JsonParseException
	 */
	public static <T> List<T> jsonToJavaBeanList(String jsonString, Class<?>... beanClasses)
			throws JsonParseException, JsonMappingException, IOException {
		JavaType javaType = mapper.getTypeFactory().constructParametricType(ArrayList.class, beanClasses);
		return (List<T>) mapper.readValue(jsonString, javaType);
	}

	/**
	 * 将一个json字符串转换为bean
	 * 
	 * @param jsonString
	 * @param _class
	 * @return
	 * @throws JsonParseException
	 * @throws JsonMappingException
	 * @throws IOException
	 */
	public static <T> T jsonToJavaBean(String jsonString, Class<T> _class)
			throws JsonParseException, JsonMappingException, IOException {
		return mapper.readValue(jsonString, _class);
	}

	/**
	 * 获取一个类的一个属性的注解值
	 * 
	 * @param _class
	 * @param annotationClass
	 * @param name
	 * @return
	 * @throws NoSuchFieldException
	 * @throws SecurityException
	 * @throws NoSuchMethodException
	 */
	public static String getClassAnnotion(Class _class, String name)
			throws NoSuchFieldException, SecurityException, NoSuchMethodException {
		return _class.getDeclaredField(name).getAnnotation(Field.class).value();
	}

	/**
	 * 将一个map映射为一个对象
	 * 
	 * @param _class
	 * @param data
	 * @return
	 */
	public static <T> T fromMapToT(Class<T> _class, Map<String, Object> data) {
		return null;
	}

	/**
	 * 将数据集根据key进行分组
	 * 
	 * @param data
	 * @return
	 */
	public static <T> Map<Object, List<T>> groupByKey(List<Map.Entry<Object, T>> data) {
		if (null == data) {
			return null;
		}

		Map<Object, List<T>> result = new HashMap<Object, List<T>>();

		for (Map.Entry<Object, T> v : data) {
			if (result.containsKey(v.getKey())) {
				result.get(v.getKey()).add(v.getValue());
			} else {
				result.put(v.getKey(), new LinkedList<T>());
				result.get(v.getKey()).add(v.getValue());
			}
		}

		return result;
	}

	/**
	 * 获取前100个字符
	 * 
	 * @param source
	 * @return
	 */
	public static String getBefore100Char(String source) {
		return getBeforeNumChar(source, 100);
	}

	/**
	 * 获取前num个字符
	 * 
	 * @param source
	 * @param num
	 * @return
	 */
	public static String getBeforeNumChar(String source, int num) {

		if (null == source || source.equals("")) {
			return source;
		}

		source = source.replaceAll("<.*?>", " ").replaceAll("[  ]+", " ");

		return source.length() > num ? source.substring(0, num) : source;
	}

	/**
	 * 分割list
	 * 
	 * @param list
	 * @param num
	 *            分割为几个
	 * @return
	 */
	public static <T> List<List<T>> splitList(List<T> list, int num) {
		if (list == null) {
			return null;
		}

		List<List<T>> t = new ArrayList<List<T>>();
		if (list.size() < num) {
			t.add(list);
			return t;
		}
		int total = list.size();
		int start = 0;
		int oneLength = total / num;
		// 比oneLength大1的数组个数
		int specialLengthNum = total % num;
		if (specialLengthNum > 0) {
			for (int i = 0; i < specialLengthNum; i++) {
				t.add(list.subList(start, (start = start + oneLength + 1)));
			}
		}
		for (int i = 0; i < num - specialLengthNum; i++) {
			t.add(list.subList(start, (start = start + oneLength)));
		}
		return t;
	}

	/**
	 * 分割数组
	 * 
	 * @param ary
	 * @param subSize
	 * @return
	 */
	public static <T> T[][] splitAry(T[] ary, int subSize) {
		int count = ary.length % subSize == 0 ? ary.length / subSize : ary.length / subSize + 1;

		List<List<T>> subAryList = new ArrayList<List<T>>();

		for (int i = 0; i < count; i++) {
			int index = i * subSize;

			List<T> list = new ArrayList<T>(subSize);
			int j = 0;
			while (j < subSize && index < ary.length) {
				list.add(ary[index++]);
				j++;
			}

			subAryList.add(list);
		}

		T[][] subAry = (T[][]) new Object[subAryList.size()][];

		for (int i = 0; i < subAryList.size(); i++) {
			List<T> subList = subAryList.get(i);

			subAry[i] = (T[]) subList.toArray();
		}

		return subAry;
	}

	/**
	 * 判断字符是否是中文
	 *
	 * @param c
	 *            字符
	 * @return 是否是中文
	 */
	public static boolean isChinese(char c) {
		Character.UnicodeBlock ub = Character.UnicodeBlock.of(c);
		if (ub == Character.UnicodeBlock.CJK_UNIFIED_IDEOGRAPHS
				|| ub == Character.UnicodeBlock.CJK_COMPATIBILITY_IDEOGRAPHS
				|| ub == Character.UnicodeBlock.CJK_UNIFIED_IDEOGRAPHS_EXTENSION_A
				|| ub == Character.UnicodeBlock.GENERAL_PUNCTUATION
				|| ub == Character.UnicodeBlock.CJK_SYMBOLS_AND_PUNCTUATION
				|| ub == Character.UnicodeBlock.HALFWIDTH_AND_FULLWIDTH_FORMS) {
			return true;
		}
		return false;
	}

	/**
	 * 判断字符串是否是乱码
	 *
	 * @param strName
	 *            字符串
	 * @return 是否是乱码
	 */
	public static boolean isMessyCode(String strName) {
		Pattern p = Pattern.compile("\\s*|\t*|\r*|\n*");
		Matcher m = p.matcher(strName);
		String after = m.replaceAll("");
		String temp = after.replaceAll("\\p{P}", "");
		char[] ch = temp.trim().toCharArray();
		float chLength = ch.length;
		float count = 0;
		for (int i = 0; i < ch.length; i++) {
			char c = ch[i];
			if (!Character.isLetterOrDigit(c)) {
				if (!isChinese(c)) {
					count = count + 1;
				}
			}
		}
		float result = count / chLength;
		if (result > 0.4) {
			return true;
		} else {
			return false;
		}

	}

	/**
	 * 将集合里的对象字符串化用 joinStr 连接
	 * 
	 * @param collection
	 * @param joinStr
	 * @return
	 */
	public static <T> String CollectionJoin(Collection<T> collection, String joinStr) {

		if (null == collection || collection.size() == 0) {
			return null;
		}

		if (StringUtils.isEmpty(joinStr)) {
			joinStr = "";
		}

		StringBuilder builder = new StringBuilder();
		int current = 0;
		int total = collection.size();
		for (T t : collection) {
			builder.append(t.toString());
			builder = current++ < total ? builder.append(joinStr) : builder;
		}
		return builder.toString();
	}

	/**
	 * 拼接数组为字符串
	 * 
	 * @param o
	 * @param flag
	 * @return
	 */
	public static <T> String join(T[] os, String flag) {
		if (null == os || os.length == 0 || null == flag) {
			return "";
		}
		StringBuffer str_buff = new StringBuffer();

		for (T t : os) {
			str_buff.append(String.valueOf(t)).append(flag);
		}

		return str_buff.deleteCharAt(str_buff.length() - 1).toString();
	}

	/**
	 * 拼接容器元素为字符串
	 * 
	 * @param o
	 * @param flag
	 * @return
	 */
	public static <T> String join(Collection<T> os, String flag) {
		if (null == os || os.size() == 0 || null == flag) {
			return "";
		}

		StringBuffer str_buff = new StringBuffer();

		for (T o : os) {
			str_buff.append(o.toString()).append(flag);
		}
		return str_buff.deleteCharAt(str_buff.length() - 1).toString();
	}

	/**
	 * 获取一个map，当key与value都不能为空时将key，value存入map再返回
	 * 
	 * @param map
	 * @param key
	 * @param value
	 * @return
	 */
	public static <K> Map<K, Object> getMap(Map<K, Object> map, K key, Object value) {
		if (null == map) {
			map = new HashMap<K, Object>();
		}
		if (null == key || null == value) {
			return map;
		}
		map.put(key, value);
		return map;
	}

	/**
	 * 查看是否有为空的参数
	 * 
	 * @param objects
	 * @return
	 * @throws NullPointerException
	 */
	public static <T extends Object> boolean objectsIsNull(T... objects) throws NullPointerException {
		String message = "不能为空";
		if (null == objects) {
			throw new NullPointerException(message);
		}
		for (Object o : objects) {
			if (null == o) {
				throw new NullPointerException(message);
			}
			if (o instanceof CharSequence && StringUtils.isEmpty((CharSequence) o)) {
				throw new NullPointerException(message);
			}
		}
		return true;
	}

	/**
	 * 从map中获取值，如果map中没有key且defaultValue不为空的情况下将key-value写入map并返回defaultValue，
	 * map中有key则返回它的值
	 * 
	 * @param data
	 * @param key
	 * @param defaultValue
	 * @return
	 */
	public static <K, V> V setGetDefaultValue(Map<K, V> data, K key, V defaultValue,boolean putValue) {
		if (null == data || null == key) {
			return defaultValue;
		}
		
		if(!data.containsKey(key)){
			if(null != defaultValue && putValue){
				data.put(key, defaultValue);
			}
			return defaultValue;
		}else{
			return data.get(key);
		}
	}
	
	/**通过分页从列表中取出子列表
	 * @param tList
	 * @param currentPage
	 * @param pageSize
	 * @return
	 */
	public static <T> List<T> fromListGetSubListByPage(List<T> tList,int currentPage,int pageSize){
		
		if(null == tList || tList.isEmpty()){
			return null;
		}
		
		int start=(currentPage-1)*pageSize;
		int end=start+pageSize;
		
		return fromListGetSubListBySE(tList,start,end);
	}
	
	/**通过起始位置从列表中取出子列表
	 * @param tList
	 * @param start
	 * @param end
	 * @return
	 */
	public static <T> List<T> fromListGetSubListBySE(List<T> tList,int start,int end){
		if((start <0 || end< 0) || (start > end) ){
			throw new IllegalArgumentException("参数不合法，start:"+start+",end:"+end);
		}
		
		if(null == tList || tList.isEmpty()){
			return null;
		}
		
		int size=tList.size();
		if(start>=size){
			return null;
		}
		
		end=end>size?size:end;
		
		List<T> tmp=tList instanceof ArrayList?tList:new ArrayList<T>(tList);
		if(start == end){
			List<T> oneElementList=new ArrayList<T>(1);
			oneElementList.add(tmp.get(start));
			return oneElementList;
		}else{
			return tmp.subList(start, end);
		}
	}
	
	/**将一个entity列表转为 id-entity 的map结构
	 * @param entityList
	 * @return
	 */
	public static <T extends AbstractDocument> Map<String,T> getId_EntityMap(List<T> entityList){
		if(null == entityList || entityList.isEmpty()){
			return null;
		}
		
		Map<String,T> id_entity=new HashMap<String,T>(entityList.size());
		for(T t:entityList){
			id_entity.put(t.getId(), t);
		}
		
		return id_entity;
	}

	public static void main(String[] args) {
		System.out.println(isMessyCode("Ã©Å¸Â©Ã©Â¡ÂºÃ¥Â¹Â³"));
		System.out.println(isMessyCode("你好"));
		System.out.println(isMessyCode("è·¨å¹´ä¸é¢"));
		
		List<String> aa=new ArrayList<String>(1);
		aa.add("a");
		System.out.println(aa.subList(0, 0));
	}
}
